package br.ufpb.di.ppgi.persistencia.query;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import br.com.caelum.vraptor.ioc.Component;
import br.ufpb.di.ppgi.negocio.modelo.aluno.Aluno;
import br.ufpb.di.ppgi.persistencia.domainstore.DomainStore;
import br.ufpb.di.ppgi.persistencia.iquery.IAlunoQuery;
import br.ufpb.di.ppgi.persistencia.pagination.HibernateQueryPagedList;
import br.ufpb.di.ppgi.util.PropertiesUtil;
import br.ufpb.di.ppgi.util.vraptor.ContainerRequestScoped;

@Component
public class AlunoQuery extends AbstractJPAHibernateQuery implements IAlunoQuery {

	public AlunoQuery(DomainStore domainStore) {
		super(domainStore);
	}

	private Criteria blank() {
		return createCriteria(Aluno.class);
	}

	private PropertiesUtil getProperties() {
		return ContainerRequestScoped.instanceFor(PropertiesUtil.class);
	}
	
	/* (non-Javadoc)
	 * @see br.ufpb.di.ppgi.persistencia.query.IUsuarioQuery#findByEmail(java.lang.String)
	 */
	public Aluno findByEmail(String email) {
		return unique(
				blank().add(Restrictions.eq("email", email))
		);
	}

	/* (non-Javadoc)
	 * @see br.ufpb.di.ppgi.persistencia.query.IUsuarioQuery#count()
	 */
	public Integer count() {
		return count(blank());
	}

	@Override
	public List<Aluno> listAll() {
		return getDomainStore().list(Aluno.class);
	}

	
	@Override
	public List<Aluno> listByOrientadorAndCanSendProposta(Long id) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.add(Calendar.MONTH, 18);
		Date data = cal.getTime();
		return list(
				blank()
				.createAlias("orientador", "o")
				.add(Restrictions.eq("o.id", id))
				.add(Restrictions.le("data_ingresso", data))
				.add(Restrictions.ge("creditos", getProperties().getInteger("proposta.quantidadeMinimaDeCreditos")))
		);
	}

	@Override
	public Aluno get(Long id) {
		return getDomainStore().get(Aluno.class, id);
	}

	@Override
	public boolean cpfExists(String cpf) {
		return count(
					blank().add(Restrictions.eq("cpf", cpf))
				) > 0;
	}


	@Override
	public HibernateQueryPagedList<Aluno> paginarByKey(String key) {
		DetachedCriteria dc = DetachedCriteria.forClass(Aluno.class);
		
		if (key != null && !key.trim().isEmpty())
			dc.add(Restrictions.ilike("nome", key,MatchMode.ANYWHERE));
				
		return new HibernateQueryPagedList<Aluno>(dc,session);
	}
	

	@Override
	public HibernateQueryPagedList<Aluno> listByOrientador(Long id,String key) {
		DetachedCriteria dc = DetachedCriteria.forClass(Aluno.class)
									.createAlias("orientador", "o")
									.add(Restrictions.eq("o.id", id));
		
		if (key != null && !key.trim().isEmpty())
			dc.add(Restrictions.ilike("nome", key,MatchMode.ANYWHERE));
				
		return new HibernateQueryPagedList<Aluno>(dc,session);
	}	

	@Override
	public Aluno findByCPF(String cpf) {
		return unique(
			blank().add(Restrictions.eq("cpf", cpf))
		);
	}
}
